//********************************************************************************************************************//
//ORGANIZATION:
//AUTHOR: bpeng(bogers.peng@gmail.com)
//SUMMARY:
//********************************************************************************************************************//
#ifndef NATIVE_SYSTEM_BASE_INTEGER_H
#define NATIVE_SYSTEM_BASE_INTEGER_H

#ifndef NATIVE_SYSTEM_BASE_OBJECT_H
#include "System/Base/Object.h"
#endif
#ifndef NATIVE_SYSTEM_BASE_EQUALTO_H
#include "System/Base/EqualTo.h"
#endif
#ifndef NATIVE_SYSTEM_BASE_COMPARE_H
#include "System/Base/Compare.h"
#endif
#ifndef NATIVE_SYSTEM_BASE_TOSTRING_H
#include "System/Base/ToString.h"
#endif

namespace Native { namespace System
{
    //****************************************************************************************************************//
    //CInteger
    //
    //****************************************************************************************************************//   
    template<typename _TNumeric>
    class NATIVE_LIBRARY_EXPORT CInteger :
        public CObject,
        public IEqualTo<CInteger<_TNumeric>>,
        public ICompare<CInteger<_TNumeric>>,
        public ICompare<_TNumeric>
    {
        NATIVE_DECLARE_OBJECT;

        NATIVE_REDEFINE(public, _TNumeric, TNumeric, T_NUMERIC);
        NATIVE_REDEFINE(public, CInteger<TNumeric>, Class, CLASS);
        
        NATIVE_DECLARE_PROPERTY(public, public, TNumeric, Value, _value);

    public:
        CInteger() :
            _value(0)
        {};

        CInteger(CLASS& that) :
            CObject(that),
            _value(that._value)
        {};

        CInteger(CLASS&& that) :
            CObject(that),
            _value(that._value)
        {};

        CInteger(TNumeric numeric) :
            _value(numeric)
        {};

        //{CObject
        virtual wstring ToString() const
        {
            return ToDecimalString();
        };
        //}
        //{IEqualTo
        virtual bool operator==(CLASS& rvalue) const
        {
            return _value == rvalue._value;
        };
        
        virtual bool operator!=(CLASS& rvalue) const
        {
            return !operator==(rvalue);
        }
        //}
        //{ICompare<CInteger<_TNumeric>>
        bool operator>(CLASS& rvalue) const
        {
            return _value > rvalue._value;
        }

        bool operator<(CLASS& rvalue) const
        {
            return _value < rvalue._value;
        }

        bool operator>=(CLASS& rvalue) const
        {
            return _value >= rvalue._value;
        }

        bool operator<=(CLASS& rvalue) const
        {
            return _value <= rvalue._value;
        }
        //}
        //{ICompare<_TNumeric>
        bool operator>(const TNumeric& rvalue) const
        {
            return _value > rvalue;
        }

        bool operator<(const TNumeric& rvalue) const
        {
            return _value < rvalue;
        }

        bool operator>=(const TNumeric& rvalue) const
        {
            return _value >= rvalue;
        }

        bool operator<=(const TNumeric& rvalue) const
        {
            return _value <= rvalue;
        }
        //}
        wstring ToDecimalString() const
        {
            return UToString::FromDecimal(_value);
        };

        wstring ToHexadecimalString() const
        {
            return UToString::FromHexadecimal(_value);
        };

        bool EqualToNumeric(TNumeric rvalue) const
        {
            return _value == rvalue;
        };

        bool NotEqualToNumeric(TNumeric rvalue) const
        {
            return !operator==(rvalue);
        };

        CLASS& operator=(CLASS& rvalue)
        {
            _value = rvalue._value;

            return *this;
        };

        CLASS& operator=(TNumeric rvalue)
        {
            _value = rvalue;

            return *this;
        };

        bool operator==(TNumeric rvalue) const
        {
            return _value == rvalue;
        };
        
        bool operator!=(TNumeric rvalue) const
        {
            return !operator==(rvalue);
        }
    };

    typedef CInteger<int8_t> Int8s;
    typedef CInteger<uint8_t> Int8u;
    typedef CInteger<int16_t> Int16s;
    typedef CInteger<uint16_t> Int16u;
    typedef CInteger<int32_t> Int32s;
    typedef CInteger<uint32_t> Int32u;
    typedef CInteger<int64_t> Int64s;
    typedef CInteger<uint64_t> Int64u;
}}

#endif